﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace PageAdmin.Utils
{
    /// <summary>
    /// 图片帮助类
    /// </summary>
    public class ImageHelper
    {
        /// <summary>
        /// 压缩图片
        /// </summary>
        /// <param name="sourceImagePath"></param>
        /// <param name="maxWidth">最大尺寸</param>
        /// <param name="quality"></param>
        /// <param name="imagePrefix"></param>
        /// <param name="delSourceImage"></param>
        /// <returns></returns>
        public static string Compress(string sourceImagePath, int maxWidth, long quality = 100, string imagePrefix = "cm_", bool delSourceImage = true)
        {
            string sourcePath = IOHelper.MapPath(sourceImagePath);
            if (!File.Exists(sourcePath))
            {
                return "";
            }
            if (maxWidth <= 0)
            {
                return sourceImagePath;
            }
            string savePath = (Path.GetDirectoryName(sourceImagePath)).Replace("\\", "/") + "/";
            string fileName = imagePrefix + Path.GetFileName(sourceImagePath);
            string fileExt = Path.GetExtension(sourceImagePath);
            int num = 0;
            string startFileName = fileName;
            while (true)
            {
                if (!File.Exists(IOHelper.MapPath(savePath + fileName)))
                {
                    break;
                }
                num++;
                fileName = (startFileName.Split('.'))[0] + "_" + num + fileExt;
            }
            string saveFile = null;
            saveFile = savePath + fileName;
            string newSavePath = IOHelper.MapPath(saveFile);
            using (Image image = Image.FromFile(sourcePath))
            {
                int width = image.Width;
                int height = image.Height;
                float B = 1;
                if (width > maxWidth)
                {
                    B = (float)maxWidth / (float)width;
                    width = maxWidth;
                    height = (int)((float)height * B);
                }
                else
                {
                    image.Dispose();//释放System.Drawing.Image
                    saveFile = sourceImagePath;
                    return saveFile;
                }
                using (Bitmap bmp= new Bitmap(width, height, PixelFormat.Format32bppPArgb))
                {
                    //建立画布
                    using (Graphics g = Graphics.FromImage(bmp)) //封装图片                         //g.Clear(Color.Transparent);//透明背景
                    {
                        g.Clear(Color.White); //白色背景
                        g.DrawImage(image, 0, 0, width, height);
                    }
                    //处理JPG质量的函数
                    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                    ImageCodecInfo ici = null;
                    foreach (ImageCodecInfo codec in codecs)
                    {
                        if (codec.MimeType == "image/jpeg")
                            ici = codec;
                    }
                    EncoderParameters ep = new EncoderParameters();
                    ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
                    bmp.Save(newSavePath, ici, ep);//存取
                }
            }
            if (delSourceImage)
            {
                IOHelper.DelFile(sourceImagePath);
            }
            return saveFile;
        }


        #region 生成缩略图

        /// <summary>
        /// 生成缩略图文件
        /// </summary>
        /// <param name="sourceImagePath">原始图片</param>
        /// <param name="thumbnailWidth">宽</param>
        /// <param name="thumbnailTheight">高</param>
        /// <param name="delSourceImage">是否删除旧文件</param>
        /// <param name="imagePrefix"></param>
        /// <returns></returns>
        public static string BuildThumbnail(string sourceImagePath, int thumbnailWidth, int thumbnailTheight, bool delSourceImage, string imagePrefix = "th", long quality = 80)
        {
            string sourcePath = IOHelper.MapPath(sourceImagePath);
            if (!File.Exists(sourcePath))
            {
                return "";
            }
            if (thumbnailWidth <= 0 && thumbnailTheight <= 0)
            {
                return sourceImagePath;
            }
            string savePath = (Path.GetDirectoryName(sourceImagePath)).Replace("\\", "/") + "/";
            string fileName = imagePrefix + Path.GetFileName(sourceImagePath);
            string fileExt = Path.GetExtension(sourceImagePath);
            int num = 0;
            string startFileName = fileName;
            while (true)
            {
                if (!File.Exists(IOHelper.MapPath(savePath + fileName)))
                {
                    break;
                }
                num++;
                fileName = (startFileName.Split('.'))[0] + "_" + num + fileExt;
            }

            string saveFile = savePath + fileName;
            string newSavePath = IOHelper.MapPath(saveFile);
            using (Image image = Image.FromFile(sourcePath))
            {
                int width = image.Width;
                int height = image.Height;
                float B = 1;
                if (width > thumbnailWidth && thumbnailWidth > 0)
                {
                    B = (float)thumbnailWidth / (float)width;
                    width = thumbnailWidth;
                    height = (int)((float)height * B);
                }
                else if (height > thumbnailTheight && thumbnailTheight > 0)
                {
                    B = (float)thumbnailTheight / (float)height;
                    height = thumbnailTheight;
                    width = (int)((float)width * B);
                }
                else
                {
                    image.Dispose();//释放System.Drawing.Image
                    saveFile = sourceImagePath;
                    return saveFile;
                }
                using(Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppPArgb))
                {
                    //建立画布
                    using (Graphics g = Graphics.FromImage(bmp))
                    {
                        //封装图片
                        //g.Clear(Color.Transparent);//透明背景
                        g.Clear(Color.White); //白色背景
                        g.DrawImage(image, 0, 0, width, height);
                    };
                    //处理JPG质量的函数
                    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                    ImageCodecInfo ici = null;
                    foreach (ImageCodecInfo codec in codecs)
                    {
                        if (codec.MimeType == "image/jpeg")
                            ici = codec;
                    }
                    EncoderParameters ep = new EncoderParameters();
                    ep.Param[0] = new EncoderParameter(Encoder.Quality, quality);
                    bmp.Save(newSavePath, ici, ep);//存取
                }
            }
            if (delSourceImage)
            {
                IOHelper.DelFile(sourceImagePath);
            }
            return saveFile;
        }

        public static bool gett()
        {
            return true;
        }

        #endregion

        #region 图片添加水印

        /// <summary>
        /// 图片添加水印
        /// </summary>
        /// <param name="imagePath">需要添加水印的图片路径</param>
        /// <param name="alpha">透明度，1-10之间的数字</param>
        /// <param name="posiotion">水印位置，1到9数字，对应9宫格</param>
        /// <param name="watermarkImagePath">水印图片路径,建议用透明png图片</param>
        /// <returns></returns>
        public static string BuildWatermark(string imagePath, int posiotion, int alpha, string watermarkImagePath)
        {
            string sourcePath = IOHelper.MapPath(imagePath);
            watermarkImagePath = IOHelper.MapPath(watermarkImagePath);
            if (!File.Exists(watermarkImagePath))
            {
                return imagePath;
            }
            if (posiotion > 9 || posiotion <= 1)
            {
                posiotion = 9;
            }
            if (alpha > 10 || alpha <= 0)
            {
                posiotion = 1;
            }
            using (Image imageSourcePath = Image.FromFile(sourcePath))
            {
                int imageSourceWidth = imageSourcePath.Width;
                int imageSourceHeight = imageSourcePath.Height;

                Image imgWatermarkIcon = Image.FromFile(watermarkImagePath);
                int imgWatermarkWidth = imgWatermarkIcon.Width; //水印图宽
                int imgWatermarkHeight = imgWatermarkIcon.Height;//水印图高

                //原始图片尺寸小于水印图片尺寸则终止
                if (imageSourceWidth <= imgWatermarkWidth || imageSourceHeight <= imgWatermarkHeight)
                {
                    imageSourcePath.Dispose();
                    imgWatermarkIcon.Dispose();
                    return imagePath;
                }
                int x = 0, y = 0;
                switch (posiotion)
                {
                    case 1:
                        x = 10;
                        y = 10;
                        break;

                    case 2:
                        x = imageSourceWidth / 2 - imgWatermarkWidth / 2;
                        y = 10;
                        break;

                    case 3:
                        x = imageSourceWidth - imgWatermarkWidth - 10;
                        y = 10;
                        break;

                    case 4:
                        x = 10;
                        y = imageSourceHeight / 2 - imgWatermarkHeight / 2;
                        break;

                    case 5:
                        x = imageSourceWidth / 2 - imgWatermarkWidth / 2;
                        y = imageSourceHeight / 2 - imgWatermarkHeight / 2;
                        break;

                    case 6:
                        x = imageSourceWidth - imgWatermarkWidth - 10;
                        y = imageSourceHeight / 2 - imgWatermarkHeight / 2;
                        break;

                    case 7:
                        x = 10;
                        y = imageSourceHeight - imgWatermarkHeight - 10;
                        break;

                    case 8:
                        x = imageSourceWidth / 2 - imgWatermarkWidth / 2;
                        y = imageSourceHeight - imgWatermarkHeight - 10;
                        break;

                    case 9:
                        x = imageSourceWidth - imgWatermarkWidth - 10;
                        y = imageSourceHeight - imgWatermarkHeight - 10;
                        break;
                }
                using (Bitmap bmp = new Bitmap(imageSourceWidth, imageSourceHeight))   //建立一个画布
                {
                    using (Graphics g = Graphics.FromImage(bmp))  //封装图片
                    {
                        //g.Clear(System.Drawing.Color.White); //清空背景颜色
                        g.DrawImage(imageSourcePath, 0, 0, imageSourceWidth, imageSourceHeight);
                        ImageAttributes imageAttributes = new ImageAttributes();
                        //ColorMap colorMap = new ColorMap();
                        //colorMap.OldColor = Color.FromArgb(255,255,255,255);
                        //colorMap.NewColor = Color.FromArgb(0,0,0,0);
                        //System.Drawing.Imaging.ColorMap[] remapTable = { colorMap };
                        //imageAttributes.SetRemapTable(remapTable, System.Drawing.Imaging.ColorAdjustType.Bitmap);
                        //用矩阵设置水印图片透明度
                        float[][] colorMatrixElements = {
               new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
               new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
               new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
               new float[] {0.0f,  0.0f,  0.0f, ((float)alpha/(float)10), 0.0f},
               new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                        };
                        ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
                        imageAttributes.SetColorMatrix(wmColorMatrix, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap);
                        g.DrawImage(imgWatermarkIcon, new Rectangle(x, y, imgWatermarkWidth, imgWatermarkHeight), 0, 0, imgWatermarkWidth, imgWatermarkHeight, GraphicsUnit.Pixel, imageAttributes); //绘制水印
                        imageAttributes.Dispose();

                        //处理JPG质量的函数
                        string fileExt = Path.GetExtension(sourcePath).ToLower();
                        ImageFormat imageFormat = ImageFormat.Jpeg;
                        switch (fileExt)
                        {
                            case ".png":
                                imageFormat = ImageFormat.Png;
                                break;

                            case ".bmp":
                                imageFormat = ImageFormat.Bmp;
                                break;

                            case ".gif":
                                imageFormat = ImageFormat.Gif;
                                break;

                            case ".ico":
                                imageFormat = ImageFormat.Icon;
                                break;

                            case ".tiff":
                                imageFormat = ImageFormat.Tiff;
                                break;
                        }

                        imageSourcePath.Dispose();
                        imgWatermarkIcon.Dispose();
                        File.Delete(sourcePath);
                        bmp.Save(sourcePath, imageFormat);//存取
                    }
                }
                return imagePath;
            }
        }

        #endregion

        /// <summary>
        /// 生成图片验证码
        /// </summary>
        /// <param name="codeLength">字符个数</param>
        /// <param name="width">图片宽</param>
        /// <param name="height">图片高</param>
        /// <param name="fontSize">字体大小</param>
        /// <param name="code">输出字符</param>
        /// <returns></returns>
        public static byte[] VerificationCode(int codeLength, int width, int height, int fontSize, out string code)
        {
            String sCode = String.Empty;
            //颜色列表
            Color[] oColors ={
                Color.Black,
                Color.Red,
                Color.OrangeRed,
                Color.Green,
                Color.Indigo,
                Color.Blue,
                Color.Brown,
                Color.DarkBlue,
                Color.Purple
            };
            //字体列表
            string[] oFontNames = { "Times New Roman", "MS Mincho", "Book Antiqua", "Gungsuh", "PMingLiU", "Impact" };
            //验证码的字符
            char[] oCharacter = {
       '2','3','4','5','6','8','9',
       'A','B','C','D','E','F','G','H','J','K', 'L','M','N','P','R','S','T','W','X','Y'
      };
            Random oRnd = new Random();
            Bitmap oBmp = null;
            Graphics oGraphics = null;
            int N1 = 0;
            Point oPoint1 = default(Point);
            Point oPoint2 = default(Point);
            string sFontName = null;
            Font oFont = null;
            Color oColor = default(Color);

            //生成随机字符
            for (N1 = 0; N1 <= codeLength - 1; N1++)
            {
                sCode += oCharacter[oRnd.Next(oCharacter.Length)];
            }
            oBmp = new Bitmap(width, height);
            oGraphics = Graphics.FromImage(oBmp);
            oGraphics.Clear(System.Drawing.Color.White);
            try
            {
                for (N1 = 0; N1 <= 4; N1++)
                {
                    //画噪线
                    oPoint1.X = oRnd.Next(width);
                    oPoint1.Y = oRnd.Next(height);
                    oPoint2.X = oRnd.Next(width);
                    oPoint2.Y = oRnd.Next(height);
                    oColor = oColors[oRnd.Next(oColors.Length)];
                    oGraphics.DrawLine(new Pen(oColor), oPoint1, oPoint2);
                }

                float spaceWith = 0, dotX = 0, dotY = 0;
                if (codeLength != 0)
                {
                    spaceWith = (width - fontSize * codeLength - 10) / codeLength;
                }

                for (N1 = 0; N1 <= sCode.Length - 1; N1++)
                {
                    //画验证码文字
                    sFontName = oFontNames[oRnd.Next(oFontNames.Length)];
                    oFont = new Font(sFontName, fontSize, FontStyle.Italic);
                    oColor = oColors[oRnd.Next(oColors.Length)];

                    dotY = (height - oFont.Height) / 2 + 2;//中心下移2像素
                    dotX = Convert.ToSingle(N1) * fontSize + (N1 + 1) * spaceWith;

                    oGraphics.DrawString(sCode[N1].ToString(), oFont, new SolidBrush(oColor), dotX, dotY);
                }

                for (int i = 0; i <= 30; i++)
                {
                    //画噪点
                    int x = oRnd.Next(oBmp.Width);
                    int y = oRnd.Next(oBmp.Height);
                    Color clr = oColors[oRnd.Next(oColors.Length)];
                    oBmp.SetPixel(x, y, clr);
                }
                code = sCode;
                //保存图片数据
                MemoryStream stream = new MemoryStream();
                oBmp.Save(stream, ImageFormat.Jpeg);
                //输出图片流
                return stream.ToArray();
            }
            finally
            {
                oBmp.Dispose();
                oGraphics.Dispose();
            }
        }
    }
}